#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "config.h"
#include "voice_recognition.h"
#include "audio_handler.h"

// 语音识别状态
static voice_recognition_state_t voice_state = VOICE_IDLE;
static char recognized_text[MAX_QUESTION_LENGTH];
static float confidence_score = 0.0f;

// 唤醒词检测
static bool wake_word_detected = false;
static uint32_t wake_word_timestamp = 0;

// 语音特征提取
typedef struct
{
    float energy;
    float zero_crossing_rate;
    float spectral_centroid;
    float mfcc[13]; // MFCC特征
} voice_features_t;

// 预定义的唤醒词特征模板
static const voice_features_t wake_word_template = {
    .energy = 0.5f,
    .zero_crossing_rate = 0.3f,
    .spectral_centroid = 1000.0f,
    .mfcc = {0.1f, 0.2f, 0.15f, 0.1f, 0.05f, 0.08f, 0.12f, 0.09f, 0.06f, 0.04f, 0.03f, 0.02f, 0.01f}};

// 私有函数声明
static void extract_voice_features(uint16_t *audio_data, int size, voice_features_t *features);
static float calculate_feature_similarity(const voice_features_t *feat1, const voice_features_t *feat2);
static bool detect_wake_word(const voice_features_t *features);
static void process_voice_command(const char *text);
static float calculate_energy(uint16_t *data, int size);
static float calculate_zero_crossing_rate(uint16_t *data, int size);
static void calculate_mfcc(uint16_t *data, int size, float *mfcc);
static void simple_speech_to_text(uint16_t *audio_data, int size, char *text);

/**
 * 初始化语音识别模块
 */
int voice_recognition_init(void)
{
    DEBUG_PRINT(2, "初始化语音识别模块...");

    // 清空识别结果
    memset(recognized_text, 0, sizeof(recognized_text));
    confidence_score = 0.0f;
    wake_word_detected = false;
    voice_state = VOICE_IDLE;

    DEBUG_PRINT(2, "语音识别模块初始化完成");
    return 0;
}

/**
 * 开始语音识别
 */
int voice_recognition_start(void)
{
    if (voice_state != VOICE_IDLE)
    {
        DEBUG_PRINT(1, "语音识别已在运行");
        return -1;
    }

    DEBUG_PRINT(2, "开始语音识别...");

    // 开始录音
    if (audio_start_recording() != 0)
    {
        DEBUG_PRINT(0, "启动录音失败");
        return -1;
    }

    voice_state = VOICE_LISTENING;
    wake_word_detected = false;

    return 0;
}

/**
 * 停止语音识别
 */
int voice_recognition_stop(void)
{
    if (voice_state == VOICE_IDLE)
    {
        return 0;
    }

    DEBUG_PRINT(2, "停止语音识别");

    // 停止录音
    audio_stop_recording();

    voice_state = VOICE_IDLE;

    return 0;
}

/**
 * 处理语音识别（在主循环中调用）
 */
void voice_recognition_process(void)
{
    if (voice_state == VOICE_IDLE)
    {
        return;
    }

    // 检查是否有语音活动
    if (!audio_detect_voice_activity())
    {
        return;
    }

    // 获取音频数据
    uint16_t audio_data[AUDIO_BUFFER_SIZE];
    int data_size = audio_get_recording_data(audio_data, AUDIO_BUFFER_SIZE);

    if (data_size <= 0)
    {
        return;
    }

    // 提取语音特征
    voice_features_t features;
    extract_voice_features(audio_data, data_size, &features);

    // 根据当前状态处理
    switch (voice_state)
    {
    case VOICE_LISTENING:
        // 检测唤醒词
        if (detect_wake_word(&features))
        {
            DEBUG_PRINT(2, "检测到唤醒词");
            wake_word_detected = true;
            wake_word_timestamp = 0; // TODO: 获取当前时间戳
            voice_state = VOICE_WAKE_WORD_DETECTED;
        }
        break;

    case VOICE_WAKE_WORD_DETECTED:
        // 唤醒词检测后，开始识别命令
        voice_state = VOICE_RECOGNIZING;
        // 继续处理...

    case VOICE_RECOGNIZING:
        // 进行语音识别
        simple_speech_to_text(audio_data, data_size, recognized_text);

        if (strlen(recognized_text) > 0)
        {
            DEBUG_PRINT(2, "识别到文本: %s", recognized_text);
            confidence_score = 0.8f; // 简化的置信度
            voice_state = VOICE_RECOGNIZED;

            // 处理识别到的命令
            process_voice_command(recognized_text);
        }
        break;

    case VOICE_RECOGNIZED:
        // 识别完成，重置状态
        voice_state = VOICE_LISTENING;
        break;

    default:
        break;
    }
}

/**
 * 获取识别结果
 */
voice_result_t voice_recognition_get_result(char *text, int max_len, float *confidence)
{
    if (voice_state != VOICE_RECOGNIZED)
    {
        return VOICE_NONE;
    }

    if (text && max_len > 0)
    {
        strncpy(text, recognized_text, max_len - 1);
        text[max_len - 1] = '\0';
    }

    if (confidence)
    {
        *confidence = confidence_score;
    }

    // 判断识别结果类型
    if (strstr(recognized_text, "练习") || strstr(recognized_text, "发音"))
    {
        return VOICE_PRACTICE;
    }
    else if (strstr(recognized_text, "什么") || strstr(recognized_text, "怎么") ||
             strstr(recognized_text, "为什么") || strstr(recognized_text, "?"))
    {
        return VOICE_QUESTION;
    }
    else
    {
        return VOICE_COMMAND;
    }
}

/**
 * 检查是否检测到唤醒词
 */
bool voice_recognition_is_wake_word_detected(void)
{
    return wake_word_detected;
}

/**
 * 重置唤醒词状态
 */
void voice_recognition_reset_wake_word(void)
{
    wake_word_detected = false;
    wake_word_timestamp = 0;
}

/**
 * 获取当前状态
 */
voice_recognition_state_t voice_recognition_get_state(void)
{
    return voice_state;
}

/**
 * 设置识别语言
 */
void voice_recognition_set_language(const char *language)
{
    DEBUG_PRINT(2, "设置识别语言: %s", language);
    // TODO: 实现语言设置
}

// 私有函数实现

/**
 * 提取语音特征
 */
static void extract_voice_features(uint16_t *audio_data, int size, voice_features_t *features)
{
    if (!features || size <= 0)
        return;

    // 计算能量
    features->energy = calculate_energy(audio_data, size);

    // 计算过零率
    features->zero_crossing_rate = calculate_zero_crossing_rate(audio_data, size);

    // 计算谱质心（简化版）
    features->spectral_centroid = features->energy * 1000.0f;

    // 计算MFCC特征
    calculate_mfcc(audio_data, size, features->mfcc);

    DEBUG_PRINT(3, "特征提取 - 能量: %.3f, 过零率: %.3f, 谱质心: %.1f",
                features->energy, features->zero_crossing_rate, features->spectral_centroid);
}

/**
 * 计算特征相似度
 */
static float calculate_feature_similarity(const voice_features_t *feat1, const voice_features_t *feat2)
{
    if (!feat1 || !feat2)
        return 0.0f;

    float similarity = 0.0f;
    int count = 0;

    // 能量相似度
    float energy_diff = fabs(feat1->energy - feat2->energy);
    similarity += 1.0f - (energy_diff > 1.0f ? 1.0f : energy_diff);
    count++;

    // 过零率相似度
    float zcr_diff = fabs(feat1->zero_crossing_rate - feat2->zero_crossing_rate);
    similarity += 1.0f - (zcr_diff > 1.0f ? 1.0f : zcr_diff);
    count++;

    // MFCC相似度
    float mfcc_similarity = 0.0f;
    for (int i = 0; i < 13; i++)
    {
        float diff = fabs(feat1->mfcc[i] - feat2->mfcc[i]);
        mfcc_similarity += 1.0f - (diff > 1.0f ? 1.0f : diff);
    }
    similarity += mfcc_similarity / 13.0f;
    count++;

    return similarity / count;
}

/**
 * 检测唤醒词
 */
static bool detect_wake_word(const voice_features_t *features)
{
    if (!features)
        return false;

    float similarity = calculate_feature_similarity(features, &wake_word_template);

    DEBUG_PRINT(3, "唤醒词相似度: %.3f", similarity);

    // 如果相似度超过阈值，认为检测到唤醒词
    return similarity > 0.7f;
}

/**
 * 处理语音命令
 */
static void process_voice_command(const char *text)
{
    if (!text || strlen(text) == 0)
        return;

    DEBUG_PRINT(2, "处理语音命令: %s", text);

    // 简单的命令处理
    if (strstr(text, "音量"))
    {
        if (strstr(text, "大") || strstr(text, "增加"))
        {
            float current_volume = audio_get_volume();
            audio_set_volume(current_volume + 0.1f);
            DEBUG_PRINT(2, "增加音量");
        }
        else if (strstr(text, "小") || strstr(text, "减少"))
        {
            float current_volume = audio_get_volume();
            audio_set_volume(current_volume - 0.1f);
            DEBUG_PRINT(2, "减少音量");
        }
    }
    else if (strstr(text, "静音"))
    {
        audio_set_mute(true);
        DEBUG_PRINT(2, "开启静音");
    }
    else if (strstr(text, "取消静音"))
    {
        audio_set_mute(false);
        DEBUG_PRINT(2, "取消静音");
    }
}

/**
 * 计算能量
 */
static float calculate_energy(uint16_t *data, int size)
{
    if (!data || size <= 0)
        return 0.0f;

    float energy = 0.0f;
    for (int i = 0; i < size; i++)
    {
        float sample = (float)data[i] / 32768.0f;
        energy += sample * sample;
    }

    return energy / size;
}

/**
 * 计算过零率
 */
static float calculate_zero_crossing_rate(uint16_t *data, int size)
{
    if (!data || size <= 1)
        return 0.0f;

    int zero_crossings = 0;
    int16_t prev_sample = (int16_t)data[0] - 32768;

    for (int i = 1; i < size; i++)
    {
        int16_t current_sample = (int16_t)data[i] - 32768;
        if ((prev_sample >= 0 && current_sample < 0) ||
            (prev_sample < 0 && current_sample >= 0))
        {
            zero_crossings++;
        }
        prev_sample = current_sample;
    }

    return (float)zero_crossings / (size - 1);
}

/**
 * 计算MFCC特征（简化版）
 */
static void calculate_mfcc(uint16_t *data, int size, float *mfcc)
{
    if (!data || !mfcc || size <= 0)
        return;

    // 简化的MFCC计算
    float energy = calculate_energy(data, size);
    float zcr = calculate_zero_crossing_rate(data, size);

    // 生成简化的MFCC特征
    for (int i = 0; i < 13; i++)
    {
        mfcc[i] = energy * (1.0f - i * 0.05f) + zcr * (i * 0.02f);
        if (mfcc[i] > 1.0f)
            mfcc[i] = 1.0f;
        if (mfcc[i] < 0.0f)
            mfcc[i] = 0.0f;
    }
}

/**
 * 简单的语音转文本（模拟实现）
 */
static void simple_speech_to_text(uint16_t *audio_data, int size, char *text)
{
    if (!audio_data || !text || size <= 0)
        return;

    // 这里是一个简化的实现，实际应该调用语音识别API
    // 根据音频特征模拟识别结果

    voice_features_t features;
    extract_voice_features(audio_data, size, &features);

    // 根据特征判断可能的文本
    if (features.energy > 0.3f && features.zero_crossing_rate > 0.2f)
    {
        if (features.spectral_centroid > 800.0f)
        {
            strcpy(text, "什么时间");
        }
        else if (features.spectral_centroid > 600.0f)
        {
            strcpy(text, "口语练习");
        }
        else
        {
            strcpy(text, "音量调节");
        }
    }
    else if (features.energy > 0.1f)
    {
        strcpy(text, "你好");
    }
    else
    {
        text[0] = '\0'; // 空字符串
    }

    DEBUG_PRINT(3, "简单语音识别结果: %s", text);
}